Repository navigation
fix(capture): end a detached table cell before writing - #494
Merged
Merged
Conversation
Obsidian keeps a Live Preview table cell after its table leaves the note's view, in Source mode or once the tab showed another note. A write through the note then reaches that cell at its old offsets. The journeys toggle Source mode or go Back after another note, change another row on disk, capture, and Undo. On master the other row loses text. A third journey captures, opens a note with a wide header cell in the same tab, edits that cell, goes Back, and clicks Undo. On master the Undo is lost. The unit cases model a cell no longer in the document, once for a capture and once for an Undo.
Source mode and opening another note in the tab replace the note's view without ending its Live Preview table cell. That cell keeps the table's old copy at its old place. A capture through it rewrote the table from that copy, and Obsidian handed the note editor's writes in the cell's old range to it, so a capture or an Undo could be lost or land in the wrong place. Before a capture or an Undo writes, a cell whose container is no longer in the document is ended with Obsidian's destroyTableCell, as Obsidian does when the note's editor takes focus. The capture then goes to the note's caret, escaped as in Source mode. A cell still in the document keeps taking captures, also in a background tab.
Deploying podnotes with
|
| Latest commit: |
cf8716d
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://9a4f0985.podnotes.pages.dev |
| Branch Preview URL: | https://fix-stale-cell-capture.podnotes.pages.dev |
This was referenced Oct 15, 2026
This was referenced Oct 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #473
Why
You edit a Live Preview table cell, then switch to Source mode or open another note in the tab. Obsidian keeps the cell's editor, but its table is gone from the view. If the note then changes elsewhere, a capture made before you click into the note rewrites the table from the cell's old copy at its old place. A row loses text, and a changed heading can delete a whole row with the capture. The same leftover cell can also swallow an Undo.
What changed
endDetachedTableCellends a table cell whose element is no longer in the document. It calls Obsidian'sdestroyTableCell, which Obsidian also calls when the note's editor takes focus. The capture then goes to the note's caret, escaped as in Source mode.Scope
Tradeoffs
Blast Radius
Only captures and Undos in a note whose tab holds a detached cell editor take the new path. If a future Obsidian drops
destroyTableCellbut keeps the cell, PodNotes keeps #471's behavior instead of throwing, and that can still corrupt the row. Obsidian 1.13.7 and 1.14.4 both have the method.Verification
npm run test:e2eon a fresh vault, Obsidian 1.14.4: 234 of 234 pass, run by an independent verifier on 88a05b3b. That commit has this change before a rebase onto two dependency bumps (build(deps-dev): bump the npm-development-minor-patch group with 4 updates #492, ci(deps): bump actions/setup-node from 7.0.0 to 7.1.0 in the github-actions group #493). The 15 table journeys pass again on the rebased head.npm run size: 102,900 gzip bytes, +57 over master's 102,843, 100 under the budget.Mutations (standing order 32), each an exact replacement in
CaptureService.ts:isShown) instead of attachmentdestroyTableCellwithout the function check"Mock only" means the unit failures come from the mock, which has neither API.
An attachment-only mutant is this fix.
Docs at release
None. The table-cell line in
timestamps.mdstays accurate.Before, master after another row changed elsewhere and Back. The other row lost text:
After, the same steps on this branch:
Before, master after the heading changed elsewhere and Back. The table is gone:
After, the same steps on this branch:
Note
Medium Risk
Changes capture/Undo write paths for notes with stale table-cell state; scope is narrow but can alter where text lands and how Undo restores notes in those edge cases.
Overview
Fixes #473 by tearing down stale Live Preview table cell editors before PodNotes writes a capture or runs capture Undo.
CaptureServicenow callsendDetachedTableCellbefore choosing the cell writer or reverting in the note editor. When Obsidian still holds a cell whose DOM node is disconnected (e.g. after Source mode or switching notes in the tab), it invokesdestroyTableCellso the timestamp goes to the current note caret instead of rewriting an obsolete table range. Connected cells—including background-tab cells—still capture through the cell editor as before; Undo uses the same cleanup so a leftover cell cannot swallow revert.Tests and the
editInTableCellmock were extended for detached cells, missingdestroyTableCell, and real-Obsidian journeys (Source/Back, background tab, Undo after another note’s stale cell).Reviewed by Cursor Bugbot for commit cf8716d. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
End detached table cells before capture writes and Undo restores
CaptureServicenow calls a newendDetachedTableCellhelper before selecting the writer, so a disconnected cell is destroyed and the capture reaches the current note editor (see CaptureService.ts).revertInUndo helper ends a stale cell the same way before restoring the captured text.Macroscope summarized cf8716d.